#pragma once

#include "matsu.h"

namespace matsu
{
	namespace mat
	{
		template <typename T>
		class MatrixStack {
		public:
			void push(T t);
			void pop();
			int size() const;
			T calc() const;
		private:
			std::vector<T> queue_;
		};

		typedef MatrixStack<mat2> mat2stack;
		typedef MatrixStack<mat3> mat3stack;
		typedef MatrixStack<mat4> mat4stack;

#if _IPHONE_
#pragma mark transform
#endif
		template<typename T>
		Matrix4<T> identity();

		template<typename T>
		Matrix4<T> translate(T x, T y, T z);
		Matrix4<float> translatef(float x, float y, float z);

		template<typename T>
		Matrix4<T> scale(T s);
		Matrix4<float> scalef(float s);

		template<typename T>
		Matrix4<T> scale(T x, T y, T z);
		Matrix4<float> scalef(float x, float y, float z);

		template<typename T>
		Matrix4<T> xRotate(T degrees);
		Matrix4<float> xRotatef(float degrees);

		template<typename T>
		Matrix4<T> yRotate(T degrees);
		Matrix4<float> yRotatef(float degrees);

		template<typename T>
		Matrix4<T> zRotate(T degrees);
		Matrix4<float> zRotatef(float degrees);

#if _IPHONE_
#pragma mark camera
#endif
		template<typename T>
		Matrix4<T> ortho(T left, T right, T bottom, T top, T near, T far);

		template<typename T>
		Matrix4<T> frustum(T left, T right, T bottom, T top, T near, T far);

		template<typename T>
		Matrix4<T> lookAt(const matsu::Vector3<T> &eye, const matsu::Vector3<T> &target, const matsu::Vector3<T> &up);

		template<typename T>
		Matrix4<T> perspective(T fovy, T aspect, T zNear, T zFar);
	}
}

#include "MTMatrixExt.hpp"
